package com.chucang.shucang.pms.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chucang.shucang.common.base.constant.CommonConstant;
import com.chucang.shucang.common.base.constant.SecurityConstant;
import com.chucang.shucang.common.base.exception.FastException;
import com.chucang.shucang.common.base.page.PageData;
import com.chucang.shucang.common.base.utils.OpsUtil;
import com.chucang.shucang.common.base.utils.R;
import com.chucang.shucang.common.oss.utils.OssUtil;
import com.chucang.shucang.common.security.annotation.Inner;
import com.chucang.shucang.pms.constant.PmsCommonConstant;
import com.chucang.shucang.pms.entity.CollectionBaseEntity;
import com.chucang.shucang.pms.exception.PmsErrorCode;
import com.chucang.shucang.pms.feign.SmsService;
import com.chucang.shucang.pms.feign.TtpService;
import com.chucang.shucang.pms.feign.vo.NFTCreateReq;
import com.chucang.shucang.pms.feign.vo.NFTOperateDTO;
import com.chucang.shucang.pms.feign.vo.PanicPurchaseVO;
import com.chucang.shucang.pms.service.CollectionBaseService;
import com.chucang.shucang.pms.vo.*;
import com.chucang.shucang.pms.vo.query.CollectionBaseQuery;
import com.github.yitter.idgen.YitIdHelper;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 藏品基础信息和发售表
 *
 * @author flitsneak flitsneak@gmail.com
 * @since 1.0.0 2022-09-12
 */
@RestController
@RequestMapping("/collectionbase")
@RequiredArgsConstructor
@Api(tags = "藏品基础信息和发售表")
public class CollectionBaseController {

    private final CollectionBaseService collectionBaseService;

    private final OssUtil ossUtil;

    private final SmsService smsService;

    private final TtpService ttpService;

    /**
     * 获取藏品基础信息
     *
     * @param id id
     * @return r
     */
    @Inner
    @Cacheable(value = "collectionBaseInfo", key = "#id")
    @GetMapping("/getCollectionBaseInfo/{id}")
    public R<CollectionBaseEntity> getCollectionBaseInfo(@PathVariable Long id) {
        CollectionBaseEntity byId = collectionBaseService.getById(id);
        return R.ok(byId);
    }

    /**
     * 藏品商城首页
     *
     * @param collectionBaseQuery cbq
     * @return r
     */
    //@Cacheable(value = "collectionsBasePage", key = "{#collectionBaseQuery.page}")
    @PostMapping("/collectionsBasePage")
    public R<PageData<CollectionBasePageResVO>> collectionsBasePage(@Valid @RequestBody CollectionBaseQuery collectionBaseQuery) {
        PageData<CollectionBasePageResVO> pageData = collectionBaseService.collectionsBasePage(collectionBaseQuery);
        return R.ok(pageData);
    }

    /**
     * 商城首页藏品详情
     *
     * @param id
     * @return
     */
    @GetMapping("/getCollectionDetail/{id}")
    public R<CollectionDetailResVO> getCollectionDetail(@PathVariable Long id) {
        CollectionDetailResVO collectionDetailResVO = collectionBaseService.getCollectionDetail(id);
        return R.ok(collectionDetailResVO);
    }

    /**
     * 更新库存
     *
     * @param id
     * @param surplus
     * @return
     */
    @Inner
    @GetMapping("/updateCollectionBase/{id}/{surplus}")
    public R<String> updateCollectionBase(@PathVariable Long id, @PathVariable Integer surplus) {
        LambdaUpdateWrapper<CollectionBaseEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CollectionBaseEntity::getId, id)
                .set(CollectionBaseEntity::getSurplus, surplus);
        collectionBaseService.update(updateWrapper);
        return R.ok();
    }

    /**
     * 新增藏品
     *
     * @param coverPicture           封面图
     * @param display                展示内容
     * @param detailPicture          详情图
     * @param collectionPreOnShelfVO 上架详情
     * @return r
     */
    @PostMapping("/addNewCollection")
    public R<String> addNewCollection(@RequestPart("coverPicture") MultipartFile coverPicture, @RequestPart("display") MultipartFile display, @RequestPart("detailPicture") MultipartFile detailPicture, @Valid CollectionPreOnShelfVO collectionPreOnShelfVO) {
        LambdaQueryWrapper<CollectionBaseEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CollectionBaseEntity::getDcName, collectionPreOnShelfVO.getDcName());
        List<CollectionBaseEntity> list = collectionBaseService.list(lambdaQueryWrapper);
        if (!CollUtil.isEmpty(list)) {
            return R.failed(PmsErrorCode.REPEAT_DC_NAME.getCode(), PmsErrorCode.REPEAT_DC_NAME.getMsg());
        }
        long l = YitIdHelper.nextId();

        String coverPictureName = coverPicture.getOriginalFilename();
        String coverSuf = FileNameUtil.getSuffix(coverPictureName);
        ossUtil.upload(coverPicture, l + "coverpicture." + coverSuf);

        String displayName = display.getOriginalFilename();
        String displaySuf = FileNameUtil.getSuffix(displayName);
        ossUtil.upload(display, l + "display." + displaySuf);

        String detailPictureName = detailPicture.getOriginalFilename();
        String detailPictureSuf = FileNameUtil.getSuffix(detailPictureName);
        ossUtil.upload(detailPicture, l + "detailpicture." + detailPictureSuf);

        String coverPictureUrl = ossUtil.getAbsoluteUrl(l + "coverpicture." + coverSuf);
        String displayUrl = ossUtil.getAbsoluteUrl(l + "display." + displaySuf);
        String detailPictureUrl = ossUtil.getAbsoluteUrl(l + "detailpicture." + detailPictureSuf);

        CollectionBaseEntity collectionBaseEntity = new CollectionBaseEntity();
        BeanUtil.copyProperties(collectionPreOnShelfVO, collectionBaseEntity);
        collectionBaseEntity.setId(l);
        collectionBaseEntity.setSurplus(collectionPreOnShelfVO.getTotalNum());
        collectionBaseEntity.setStartTime(DateUtil.parse(collectionPreOnShelfVO.getSStartTime()));
        collectionBaseEntity.setEndTime(DateUtil.parse(collectionPreOnShelfVO.getSEndTime()));
        collectionBaseEntity.setCoverPicture(coverPictureUrl);
        collectionBaseEntity.setDcDisplay(displayUrl);
        collectionBaseEntity.setDetailPicture(detailPictureUrl);

        collectionBaseService.save(collectionBaseEntity);
        return R.ok();
    }

    /**
     * 上架藏品
     *
     * @param collectionOnShelfVO cov
     * @return r
     */
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/collectionOnShelf")
    public R<String> collectionOnShelf(@Valid @RequestBody CollectionOnShelfVO collectionOnShelfVO) {
        CollectionBaseEntity byId = collectionBaseService.getById(collectionOnShelfVO.getCollectionId());
        LambdaUpdateWrapper<CollectionBaseEntity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(CollectionBaseEntity::getId, collectionOnShelfVO.getCollectionId())
                .set(CollectionBaseEntity::getDcPrice, new BigDecimal(collectionOnShelfVO.getDcPrice()))
                .set(CollectionBaseEntity::getStartTime, DateUtil.parse(collectionOnShelfVO.getSStartTime()))
                .set(CollectionBaseEntity::getEndTime, DateUtil.parse(collectionOnShelfVO.getSEndTime()))
                .set(CollectionBaseEntity::getStatus, PmsCommonConstant.ON_SHELF);
        //更新描述商品表
        PanicPurchaseVO panicPurchaseVO = new PanicPurchaseVO();
        panicPurchaseVO.setPurchaseNum(collectionOnShelfVO.getPerLimit());
        panicPurchaseVO.setProductType(PmsCommonConstant.COLLECTION);
        panicPurchaseVO.setProductId(collectionOnShelfVO.getCollectionId());
        R<String> r = smsService.addNewPanicPurchase(panicPurchaseVO, SecurityConstant.FROM_IN);
        OpsUtil.of(r)
                .assertCode(CommonConstant.SUCCESS, e -> new FastException("更新抢购信息异常！"));
        collectionBaseService.update(lambdaUpdateWrapper);
        //类别上链
        NFTCreateReq nftCreateReq = new NFTCreateReq();
        nftCreateReq.setClass_id(CommonConstant.CLASS_ID_PREFIX + collectionOnShelfVO.getCollectionId());
        nftCreateReq.setName(byId.getDcName());
        nftCreateReq.setOwner(CommonConstant.CHUCANG_OFFSHORE_ACCOUNT);
        nftCreateReq.setOperation_id(collectionOnShelfVO.getCollectionId().toString());
        R<NFTOperateDTO> nft = ttpService.createNFT(nftCreateReq);
        OpsUtil.of(nft)
                .assertCode(CommonConstant.SUCCESS, e -> new FastException("上链失败，请及时处理！"));
        return R.ok();
    }

    /**
     * 下架藏品
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @GetMapping("/collectionOffShelf/{id}")
    public R<String> collectionOffShelf(@PathVariable Long id) {
        LambdaUpdateWrapper<CollectionBaseEntity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(CollectionBaseEntity::getId, id)
                .set(CollectionBaseEntity::getStatus, PmsCommonConstant.NOT_ON_SHELF);
        R<String> r = smsService.offPanicPurchase(id, SecurityConstant.FROM_IN);
        OpsUtil.of(r)
                .assertCode(CommonConstant.SUCCESS, e -> new FastException("更改秒杀状态失败！"));
        collectionBaseService.update(lambdaUpdateWrapper);
        return R.ok();
    }

    /**
     * 获取可合成藏品信息
     *
     * @return
     */
    @GetMapping("/listSyntheticCollections")
    public R<List<CollectionBaseSyntheticResVO>> listSyntheticCollections() {
        LambdaQueryWrapper<CollectionBaseEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CollectionBaseEntity::getStatus, 0)
                .eq(CollectionBaseEntity::getDcAttribute, 2)
                .gt(CollectionBaseEntity::getEndTime, new Date());
        List<CollectionBaseEntity> list = collectionBaseService.list(lambdaQueryWrapper);
        List<CollectionBaseSyntheticResVO> collectionBaseSyntheticResVOS = BeanUtil.copyToList(list, CollectionBaseSyntheticResVO.class);
        return R.ok(collectionBaseSyntheticResVOS);
    }

}